<?php

/**
 * @author jinanav 2020年1月13日16:40:38
 * @desc 自定义Redis服务类
 */
class RedisService{

    //redis操作对象
    private static $redis = null;
    private static $dbid = 3;
    //全局用户token
    private static $token = null;
    //全局user信息
    private static $user = null;
    //前缀
    private static $fix = "token_";

    /**
     * 初始化
     */
    public function __construct(){
        if(empty(self::$redis)){
            $port=REDIS_PORT;
            $host=REDIS_HOSTNAME;
            $password=REDIS_PASSWORD;
            self::$redis = new Redis();
            self::$redis->connect($host,$port,5);
            if($password){
                self::$redis->auth($password);
            }
            self::$redis->select(self::$dbid);
        }
        //这里用到tp5.1的门面
        //!empty(Request::header('token')) && self::$token = Request::header('token');
    }
    
    public function dbselect($db=3,$fix="token_"){
        // 选择操作的库
        self::$dbid=$db;
        // 设置前缀
        self::$fix=$fix;
    }

    /**
     * 初始化
     */
    public static function init($db=3){
        // 选择操作的库
        self::$dbid=$db;
        new static();
    }

    /**
     * 根据token获取当前登录用户
     * @author jinanav 2020年1月13日16:40:57
     * @return array | string | null
     */
    public static function getUser($key = null){
        if(!isset(self::$user[$key]) || empty(self::$user[$key])){
            if (empty(self::$token)) return null;
            self::$user = self::$redis->get(self::$token);
            self::$user = empty(self::$user) ? [] : json_decode(self::$user,true);
        }
        return empty($key) ? self::$user : self::$user[$key] ?? null;
    }

    /**
     * 设置用户登录信息
     * @author jinanav 2020年1月13日17:47:15
     * @param array $user 用户信息
     * @param int $timeout 失效时间
     * @return array|bool
     */
    public static function setUser($userInfo,$timeout = 86400 * 7){
        // empty(self::$token) && self::$token = self::createToken($userInfo['uid'] ?? 0);
        // self::$user = array_merge(self::getUser(),$userInfo);
        return self::$redis->set(self::$token,json_encode($userInfo),$timeout);
    }

    /**
     * 注销用户
     * @author jinanav 2020年1月17日15:53:11
     * @return bool
     */
    public static function delUser($token = null){
        return self::$redis->del(empty($token) ? self::$token : $token);
    }

    /**
     * 根据用户uid生成token
     * @author jinanav 2020年1月13日17:47:15
     * @param int $string 用户识别字符串
     * @retrun string;
     */
    public static function createToken($string){
        return self::$fix.strtoupper(md5($string.time().rand(100,999)));
        // return self::$fix.strtoupper(md5($string));
    }

    /**
     * 统计key长度，默认获取当前在线用户
     * @author jinanav 2020年1月13日19:45:03
     * @return int
     */
    public static function onLineNumber($key = null){
        empty($key) && $key = self::$fix."*";
        return count(self::$redis->keys($key));
    }
    public static function test($key = null){
        // return self::$redis->info();
        return self::$redis->keys('*');
        return self::$redis->hGet('*',3);
    }
    public static function onLineList($key = null){
        empty($key) && $key = self::$fix."*";
        $keylist=self::$redis->keys($key);
        return $keylist;
    }

    /**
     * 校验是否需要登录
     * @author jinanav 2020年1月19日14:56:29
     * @param bool $needLogin 是否需要登录
     * @return string Json
     */
    public static function loginStatus($needLogin = false){
        if(self::existKey()){
            return true;
        }elseif ($needLogin) {
           ajaxReturn(302,'请先到登录...');
        }else{
            return false;
        }
        // return (self::existKey() ? true : $needLogin ? ajaxReturn(302,'请先到登录...') : false);
    }

    /**
     * 查询当前token是否存在
     * @author jinanav 2020年1月19日14:59:26
     * @return bool
     */
    public static function existKey($key = null){
        return self::$redis->exists(!empty($key) ? $key : self::$token);
    }


    /**
     * 日志数据写入队列
     * @author jinanav 2020年1月17日15:05:06
     * @param array $data 写入队列的消息
     * @param string $queue 队列key名称 与日志表名相关联
     * @return boolean
     */
    public static function enqueue($data,$queue = 'api_queue'){
        //MQ过长不予写入，建议自定义长度
        if(self::queueLen($queue) < 8000 && !empty($data)){
            return self::$redis->lPush($queue,json_encode($data));
        }
        return false;
    }

    /**
     * 读取队列数据
     * @author jinanav 2020年1月17日15:11:44
     * @param string $queue 队列key名称
     * @return array
     */
    public static function dequeue($queue = 'api_queue'){
        $info = self::$redis->rPop($queue);
        return !empty($info) ? json_decode($info,true) : [];
    }

    /**
     * 返回队列长度
     * @author jinanav 2020年1月17日17:23:32
     * @param string $queue 队列key名称
     * @return int
     */
    public static function queueLen($queue = 'api_queue'){
        return self::$redis->lLen($queue);
    }

    /**
     * 查看队列列表
     * @param string $queue
     * @author shaochao 2020/4/3 21:35
     * @return
     */
    public static function lRange($queue = 'api_queue',$start=0,$end=10){
        return self::$redis->lRange($queue,$start,$end);
    }

    /**
     * 获取当前token
     * @author jinanav 2020年3月6日15:35:44
     * @return string|null
     */
    public static function getToken(){
        return self::existKey() ? self::$token : null;
    }

    /**
     * 设置当前token
     * @author jinanav 2020年3月6日15:35:44
     * @return string
     */
    public static function setToken($token){
        self::$token = $token;
    }

    /**
     * 返回当前redis操作对象
     * @author jinanav 2020年4月21日15:32:57
     * @return \Redis
     */
    public static function op(){
        return self::$redis;
    }

    /**
     * 删除键
     * @author jinanav 2020年6月4日00:13:12
     * @return bool
     */
    public static function remove($key){
        return self::$redis->del($key);
    }

    /**
     * 查看指定键的生存时间
     * @author jinanav 2020年6月4日00:13:12
     * @return bool
     */
    public static function ttl($key = null){
        return self::$redis->ttl(empty($key) ? self::$token : $key);
    }

    /**
     * 设置指定键的过期时间
     * @author jinanav 2020年6月29日00:29:25
     * @return bool
     */
    public static function expire($timeout = 600,$key = null){
        return self::$redis->expire(empty($key) ? self::$token : $key,$timeout);
    }

    /**
     * 写新值，并返回旧值
     * @author jinanav 2020年6月29日00:29:25
     * @return bool
     */
    public static function getSet($key,$value){
        return self::$redis->GetSet(empty($key) ? self::$token : $key,$value);
    }

    /**
     * 将value绑定到key，并重置过期时间
     * @author jinanav 2020年6月29日00:29:25
     * @return bool
     */
    public static function setex($key,$value,$timeOut){
        return self::$redis->setex(empty($key) ? self::$token : $key,$timeOut,$value);
    }
}